package com.piece.admin.controller.front;

import com.piece.admin.api.dto.SysDictDTO;
import com.piece.admin.controller.ControllerSupport;
import com.piece.admin.model.TbSysDict;
import com.piece.admin.service.TbSysDictService;
import com.piece.admin.service.TbSysUserService;
import com.piece.core.framework.constant.ApplicationConstants;
import com.piece.core.framework.constant.ExceptionConstants;
import com.piece.core.framework.util.collection.CollectionUtil;
import com.piece.core.framework.util.location.IPAddressFactory;
import com.piece.core.framework.util.object.BeanUtil;
import com.piece.core.mongo.service.MongoLoginLogService;
import com.piece.core.framework.support.bootstrap.DataTable;
import com.piece.core.framework.support.bootstrap.QueryTable;
import com.piece.core.framework.support.bootstrap.Valid;
import com.piece.core.framework.support.convert.Convert;
import com.piece.core.framework.support.response.AjaxResponse;
import com.piece.core.framework.util.cache.CacheFactory;
import com.piece.core.framework.util.math.RandomUtil;
import com.piece.core.framework.util.net.HttpUtil;
import com.piece.core.framework.util.net.IpUtil;
import com.piece.core.framework.util.net.WeatherUtil;
import com.piece.core.framework.util.object.ClassUtil;
import com.piece.core.framework.util.basic.I18nUtil;
import com.piece.core.framework.util.string.StringUtil;
import com.piece.core.framework.util.time.DateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Controller
@Api(tags = {"对外访问管理"})
public class PublicController extends ControllerSupport {

    private final String bjbus_url = "http://www.bjbus.com/home/ajax_rtbus_data.php";

    @Autowired
    private IPAddressFactory ipAddressFactory;

    @Autowired
    private CacheFactory cacheFactory;

    @Resource
    private TbSysUserService tbSysUserService;

    @Resource
    private TbSysDictService tbSysDictService;

    @Resource
    private MongoLoginLogService mongoLoginLogService;

    @ResponseBody
    @GetMapping("/public/copyright")
    @ApiOperation(value = "加载版权信息")
    public AjaxResponse copyright() {
        try {
            return success(I18nUtil.message(ExceptionConstants.MESSAGE_SUCCESS), applicationProperties.getValue(ApplicationConstants.COPYRIGHT));
        } catch (Exception e) {
            return success(I18nUtil.message(ExceptionConstants.MESSAGE_ERROR), "");
        }
    }

    @ResponseBody
    @GetMapping("/public/weather")
    @ApiOperation(value = "加载天气信息")
    public AjaxResponse weather() {
        try {
            String cityName = ipAddressFactory.getCity(IpUtil.getIp(getRequest(), true));
            String cityCode = WeatherUtil.getInstance().getCityCode(cityName);
            if (null == cityCode) {
                cityName = "北京";
                cityCode = "101010100";
            }
            Map weather = cacheFactory.get().getMap("WeatherInto-" + cityCode);
            if (ClassUtil.isEmpty(weather)) {
                weather = WeatherUtil.getInstance().getCityWeather(cityCode);
                // 第二天早4点过期
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(DateUtil.addDay(1));
                calendar.set(Calendar.HOUR_OF_DAY, 4);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                long expire = calendar.getTimeInMillis() - new Date().getTime();
                cacheFactory.get().setMap("WeatherInto-" + cityCode, weather, expire/1000);
            }

            Map today = new HashMap();
            today.put("city", cityName);
            today.put("type", weather.get("type"));
            today.put("wendu", weather.get("wendu"));
            today.put("shidu", weather.get("shidu"));
            today.put("high", weather.get("high"));
            today.put("low", weather.get("low"));
            today.put("fx", weather.get("fx"));
            today.put("fl", weather.get("fl"));
            today.put("pm25", weather.get("pm25"));
            today.put("quality", weather.get("quality"));
            today.put("canvas", weather.get("canvas"));
            Map forecast = WeatherUtil.getInstance().transToCharts(weather);
            Map response = new HashMap();
            response.put("today", today);
            response.put("forecast", forecast);
            return success(I18nUtil.message(ExceptionConstants.MESSAGE_SUCCESS), response);
        } catch (Exception e) {
            return error(I18nUtil.message(ExceptionConstants.MESSAGE_ERROR), e.getMessage());
        }
    }

    @ResponseBody
    @GetMapping("/public/visit/chart")
    @ApiOperation(value = "网站访问量统计")
    @ApiImplicitParam(name = "days", value = "查询之前天数，默认前3天")
    public AjaxResponse visitChart() {
        int days = Convert.toInt(getRequest().getParameter("days"), 3);
        try {
            return success(I18nUtil.message(ExceptionConstants.MESSAGE_SUCCESS), mongoLoginLogService.findVisitCharts(days));
        } catch (Exception e) {
            return error(I18nUtil.message(ExceptionConstants.MESSAGE_ERROR), e.getMessage());
        }
    }

    @ResponseBody
    @GetMapping("/public/visit/map")
    @ApiOperation(value = "网站访问分布地统计")
    @ApiImplicitParam(name = "type", value = "查询分类，日、周、月")
    public AjaxResponse visitMap() {
        String type = getRequest().getParameter("type");
        try {
            return success(I18nUtil.message(ExceptionConstants.MESSAGE_SUCCESS), mongoLoginLogService.findVisitMapCharts(Convert.toInt(type, 0)));
        } catch (Exception e) {
            return error(I18nUtil.message(ExceptionConstants.MESSAGE_ERROR), e.getMessage());
        }
    }

    @ResponseBody
    @GetMapping("/public/bus/dir")
    @ApiOperation(value = "查询公交方向")
    @ApiImplicitParam(name = "selBLine", value = "公交路线")
    public AjaxResponse selBDir() {
        String selBLine = getRequest().getParameter("selBLine");
        String url = bjbus_url + "?act=getLineDirOption&selBLine=" + selBLine;
        try {
            return  HttpUtil.get(url).execute().html();
        } catch (Exception e) {
            return AjaxResponse.error(e.getMessage());
        }
    }

    @ResponseBody
    @GetMapping("/public/bus/stop")
    @ApiOperation(value = "查询公交站点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "selBLine", value = "公交路线"),
            @ApiImplicitParam(name = "selBDir", value = "路线方向")
    })
    public AjaxResponse selBStop() {
        String selBLine = getRequest().getParameter("selBLine");
        String selBDir = getRequest().getParameter("selBDir");
        try {
            String url = bjbus_url + "?act=getDirStationOption&selBLine=" + selBLine + "&selBDir=" + selBDir;
            return HttpUtil.get(url).execute().html();
        } catch (Exception e) {
            return AjaxResponse.error(e.getMessage());
        }
    }

    @ResponseBody
    @GetMapping("/public/bus/time")
    @ApiOperation(value = "查询实时公交信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "selBLine", value = "公交路线"),
            @ApiImplicitParam(name = "selBDir", value = "路线方向"),
            @ApiImplicitParam(name = "selBStop", value = "公交站点")
    })
    public AjaxResponse selBTime() {
        String selBLine = getRequest().getParameter("selBLine");
        String selBDir = getRequest().getParameter("selBDir");
        String selBStop = getRequest().getParameter("selBStop");
        String url = bjbus_url + "?act=busTime&selBLine=" + selBLine + "&selBDir=" + selBDir + "&selBStop=" + selBStop;
        return HttpUtil.get(url).execute().html();
    }

    @ResponseBody
    @PostMapping("/public/demo/table")
    @ApiOperation(value = "查询分页数据Demo")
    public AjaxResponse table() {
        QueryTable queryTable = initTable();
        DataTable dataTable = new DataTable(queryTable);
        List<Map<String, String>> data = new ArrayList<>();
        for (int i = 0; i< 20; i++) {
            Map<String, String> row = new HashMap<>();
            row.put("ID", i + "");
            row.put("NAME", RandomUtil.randomName());
            row.put("AGE", RandomUtil.randomNumbers(2));
            data.add(row);
        }

        dataTable.setData(data);
        return success(dataTable);
    }

    @ResponseBody
    @GetMapping("/public/demo/autocomplete/user")
    @ApiOperation(value = "查询用户自动补全")
    public AjaxResponse autocomplete() throws Exception {
        List<Map<String, String>> users = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Map<String, String> user = new HashMap<>();
            user.put("userId", RandomUtil.randomNumbers(9));
            user.put("loginName", RandomUtil.randomName());
            users.add(user);
        }

        AjaxResponse response = success(users);
        return response;
    }

    @ResponseBody
    @GetMapping("/public/demo/typeahead/user")
    @ApiOperation(value = "查询用户自动补全")
    public AjaxResponse typeahead() throws Exception {
        List<String> names = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            names.add(RandomUtil.randomName());
        }

        AjaxResponse response = success(names);
        return response;
    }

    @ResponseBody
    @GetMapping("/public/user/unique")
    @ApiOperation(value = "检查用户是否重复")
    public Valid checkUserIsUnique() {
        String userId = getRequest().getParameter("userId");
        String loginName = getRequest().getParameter("loginName");
        String email = getRequest().getParameter("email");
        String mobile = getRequest().getParameter("mobile");
        boolean result = true;
        Valid valid = new Valid();

        if (StringUtil.isNotEmpty(loginName))
            result = tbSysUserService.checkLoginNameUnique(Convert.toLong(userId), loginName);
        if (StringUtil.isNotEmpty(email))
            result = tbSysUserService.checkEmailUnique(Convert.toLong(userId), email);
        if (StringUtil.isNotEmpty(mobile))
            result = tbSysUserService.checkPhoneUnique(Convert.toLong(userId), mobile);

        valid.setValid(result);
        return valid;
    }

    /**
     * 查询网站配置项
     */
    @ResponseBody
    @GetMapping("/public/options")
    @ApiOperation(value = "查询网站配置项")
    public AjaxResponse getSiteOptions() {
        String key = getRequest().getParameter("key");
        return success(applicationProperties.getValue(key));
    }

    /**
     * 加载字典下拉选项
     */
    @ResponseBody
    @GetMapping("/public/dict/group")
    @ApiOperation(value = "加载字典下拉菜单")
    @ApiImplicitParam(name = "group", value = "字典所属组名")
    public List<SysDictDTO> getDataGroup() {
        String group = getRequest().getParameter("group");
        List<TbSysDict> dictList = tbSysDictService.findByDicGroup(group);
        return CollectionUtil.convertList(dictList, dict -> {
           SysDictDTO sysDict = new SysDictDTO();
            BeanUtil.copyProperties(dict, sysDict, true);
            return sysDict;
        });
    }

    @ResponseBody
    @GetMapping("/public/version/check")
    @ApiOperation(value = "检查应用版本")
    public AjaxResponse checkVersion() {
        String type = getRequest().getParameter("type");
        String version = "";
        if ("desktop".equals(type)) {
            version = applicationProperties.getValue(ApplicationConstants.PC_VERSION);
        } else {
            version = applicationProperties.getValue(ApplicationConstants.APP_VERSION);
        }
        return success(version);
    }

    @GetMapping({"/error/403", "/403"})
    @ApiOperation(value = "跳转403无权限页面")
    public ModelAndView unAuth() {
        return new ModelAndView("/error/403");
    }

    @GetMapping({"/error/404", "/404"})
    @ApiOperation(value = "跳转404页面")
    public ModelAndView err404() {
        setBaseModel();
        return new ModelAndView("/error/404");
    }

    @GetMapping({"/error/500", "/500"})
    @ApiOperation(value = "跳转500页面")
    public ModelAndView err500() {
        setBaseModel();
        return new ModelAndView("/error/500");
    }
}
